#coding=utf-8
from __future__ import print_function
from twisted.internet.protocol import Factory,ClientFactory
from twisted.internet import reactor,protocol,endpoints,defer
from twisted.python import log,logfile
import socket,os,sys
os.chdir(os.path.dirname(os.path.abspath(__file__)))
f = logfile.DailyLogFile("log.txt",os.path.dirname(os.path.abspath(__file__)))
log.startLogging(f)

bindUser = {}
clientUser = []
remote_address = ("127.0.0.1", 9999)


def workClient(x):
    #锁定客户端不能超过3个
    if len(clientUser) <=3:
        cx = endpoints.TCP4ClientEndpoint(reactor,"127.0.0.1",9999)
        cx.connect(SomeClientProtocolFactory(bindUser=bindUser,clientUser=clientUser))
    print(x)


class SomeClientProtocol(protocol.Protocol):
    def __init__(self,user):
        self.user = user

    def connectionMade(self):
        print("SomeClientProtocol connectionMade conn .........")
        self.user.clientUser.append(self)

    def dataReceived(self, data):
        self.user.bindUser[self].transport.write(data)

    def connectionLost(self, reason):
        #关闭连接
        self.transport.abortConnection()
        print("SomeClientProtocol connectionLost....")
        if self in self.user.bindUser:
            del self.user.bindUser[self]

        #创建新客户端
        d = defer.Deferred()
        d.addCallback(workClient)
        d.callback("workClient init .........")


class SomeClientProtocolFactory(protocol.ClientFactory):
    def __init__(self,bindUser,clientUser):
        self.bindUser = bindUser
        self.clientUser = clientUser

    def buildProtocol(self, addr):
        print("SomeClientProtocolFactory init .........")
        return SomeClientProtocol(self)

class MstscServer(protocol.Protocol):
    def __init__(self,user):
        self.user = user
        self.initWhiteList()
        self.clinetMark=True

    def connectionMade(self):
        host = self.transport.getPeer().host
        print("There are new  connections %s" % host)
        log.msg("There are new  connections %s" % host)

        if self.user.whitelistMark == "0":
            print("The white list is not open")
            log.msg("The white list is not open")
            c1 = self.user.clientUser.pop()
            self.user.bindUser[self] = c1
            self.user.bindUser[c1]   = self

        else:
            print("White list open")
            log.msg("White list open")
            if self.whiteList(host):
                print("White list verification passed:%s" % host)
                log.msg("White list verification passed:%s" % host)
                c1 = self.user.clientUser.pop()
                self.user.bindUser[self] = c1
                self.user.bindUser[c1] = self


            else:
                print("Whitelist verification failed:%s" % host)
                log.msg("Whitelist verification failed:%s" % host)
                del self

    def connectionLost(self, reason):
        print(("bengin close client",self.user.bindUser))
        if self in self.user.bindUser:
            #触发绑定客户端关闭
            self.user.bindUser[self].connectionLost(self)
            del self.user.bindUser[self]

        print(("end close client", self.user.bindUser))

    def dataReceived(self, data):
        try:
            self.user.bindUser[self].transport.write(data)
        except Exception as e:
            print(e)

    def whiteList(self,host):
        with open("whitelist.txt") as f:
            f_data = f.read()
        if host in f_data:
            return True
        else:
            return False

    def initWhiteList(self):
        if not os.path.isfile("whitelist.txt"):
            with open("whitelist.txt","w") as f:
                f.write()



class MstscServerFactory(Factory):
    def __init__(self,bindUser,clientUser,whitelistMark="0"):
        self.bindUser=bindUser
        self.clientUser = clientUser
        self.whitelistMark=whitelistMark
        self.remote_address = remote_address
    def buildProtocol(self, addr):
        return MstscServer(self)


if __name__ == '__main__':
    listenPort = 8888

    try:
        if sys.argv[1] == "1":
            mstscServerFactory = MstscServerFactory(whitelistMark="1",bindUser=bindUser,clientUser=clientUser)
            log.msg("White list open")
    except Exception:
        log.msg("white list off")
        mstscServerFactory = MstscServerFactory(whitelistMark="1",bindUser=bindUser,clientUser=clientUser)

    #初始化3个客户端
    c1 = endpoints.TCP4ClientEndpoint(reactor,remote_address[0],remote_address[1])
    c1.connect(SomeClientProtocolFactory(bindUser=bindUser,clientUser=clientUser))

    c2 = endpoints.TCP4ClientEndpoint(reactor,remote_address[0],remote_address[1])
    c2.connect(SomeClientProtocolFactory(bindUser=bindUser,clientUser=clientUser))

    c3 = endpoints.TCP4ClientEndpoint(reactor,remote_address[0],remote_address[1])
    c3.connect(SomeClientProtocolFactory(bindUser=bindUser,clientUser=clientUser))

    reactor.listenTCP(listenPort,mstscServerFactory)
    reactor.run()